home *** CD-ROM | disk | FTP | other *** search
- /*
- jpegdump.c - dump JPEG marker information
-
- v1.00 1992.06.09 initial release
- v1.01 1992.06.22 non-JFIF APP0 markers didn't display first five bytes
- v1.02 1992.07.20 eliminated fseeks which seem to be broken, even for
- forward seeks only, on pipes on some systems
- v1.03 1992.08.24 added offset and stop at eoi options
- v1.04 1992.08.24 added parsing of JFIF extension markers as per JFIF
- v1.02 draft of 1992.08.21
- v1.05 1992.08.25 added -r to recurse into JPEG compressed thumbnails
- (completely untested; probably doesn't work)
- v1.06 1992.09.14 incorporated Phil Richards' code to guess cjpeg quality
- factor
- v1.07 1992.09.15 added extension 0x13 per final JFIF 1.02; repaired bugs
- in thumbnail-related code
- v1.08 1992.12.23 Provide multiple levels of verbosity; miscellaneous
- cleanups
- v1.09 1993.03.01 Add switch for hex/char printout of COM,APPn data
- v1.10 1993.10.26 Identify -q 100 quant tables correctly; more tweaking
- of verbosity levels
-
- Copyright (c) 1992 Handmade Software, Inc.
- by Allan N. Hessenflow
-
- Permission to use, copy, modify, and distribute this software and
- its documentation for any purpose and without fee is hereby granted,
- provided that the above copyright notice appear in all copies and
- that both that copyright notice and this permission notice appear in
- supporting documentation. This software is provided "as is" without
- express or implied warranty.
-
-
- Usage:
- jpegdump [-help] [-q] [-v] [-o n] [-c] [-noc] [-r] [-nor] [-hex] [-nohex]
- [file1 [file2...]]
-
- -q quiet: minimal information printed
- -v verbose: more information printed (multiple -v's give more output)
- -o n skip first n bytes of file (1234 is decimal, 0x1234 for hex)
- -c continue past EOI to actual end of file (default)
- -noc stop upon seeing EOI marker
- -r recurse into jpeg compressed thumbnails (use at your own risk)
- -nor don't recurse into thumbnails (default)
- -hex show COM and APPn data in hex
- -nohex show COM and APPn data in ASCII when possible (default)
-
- The numbers printed in the `Approximate quality factor' line are as follows:
- Quality: an estimate of the quality factor used when cjpeg was run.
- Scaling factor (scale): mean ratio between quantization table entries
- and JPEG sample table entries, times 100.
- Variance (var): squared standard deviation of the above ratio.
- If this is larger than about 2, then the table is not a simple
- multiple of the standard's sample table, so the file was NOT
- generated by cjpeg and the quality estimate is dubious.
-
- Bugs:
- garbage in, garbage out
-
-
- Build instructions:
- MSC v7.00 (substitute the path to setargv.obj for \c700\lib\):
- cl jpegdump.c \c700\lib\setargv.obj /link /NOE
- Watcom C/386 v9.0 (substitute the path to wildargv.c for \watcom\src\starup\)
- wcl386 jpegdump.c \watcom\src\startup\wildargv.c
- acc:
- acc jpegdump.c -o jpegdump
- gcc:
- gcc jpegdump.c -o jpegdump
- others:
- any ANSI C compiler should work. If you don't define CASESENSITIVE
- then you may need to provide your own strnicmp on some systems; this
- is just a case insensitive version of strncmp. If you're too lazy
- to do that, just define CASESENSITIVE and be sure to enter the
- switches in lower case.
-
-
- Bug reports, comments to:
- allanh@netcom.com
- */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <ctype.h>
- #ifdef MSDOS
- #include <fcntl.h> /* for setmode() call */
- #endif
-
- #ifdef CASESENSITIVE /* set to disable use of strnicmp */
- #define strnicmp(a,b,len) strncmp(a,b,len)
- #endif
-
-
- /* JPEG marker codes */
- #define TEM 0x01
- #define SOF 0xc0
- #define DHT 0xc4
- #define JPGA 0xc8
- #define DAC 0xcc
- #define RST 0xd0
- #define SOI 0xd8
- #define EOI 0xd9
- #define SOS 0xda
- #define DQT 0xdb
- #define DNL 0xdc
- #define DRI 0xdd
- #define DHP 0xde
- #define EXP 0xdf
- #define APP 0xe0
- #define JPG 0xf0
- #define COM 0xfe
-
- /* Sample quantization tables from JPEG spec --- only needed for
- * guesstimate of quality factor
- */
- static int std_luminance_quant_tbl[64] = {
- 16, 11, 12, 14, 12, 10, 16, 14,
- 13, 14, 18, 17, 16, 19, 24, 40,
- 26, 24, 22, 22, 24, 49, 35, 37,
- 29, 40, 58, 51, 61, 60, 57, 51,
- 56, 55, 64, 72, 92, 78, 64, 68,
- 87, 69, 55, 56, 80, 109, 81, 87,
- 95, 98, 103, 104, 103, 62, 77, 113,
- 121, 112, 100, 120, 92, 101, 103, 99
- };
-
- static int std_chrominance_quant_tbl[64] = {
- 17, 18, 18, 24, 21, 24, 47, 26,
- 26, 47, 99, 66, 56, 66, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99
- };
-
- static int *deftabs[2] =
- { std_luminance_quant_tbl, std_chrominance_quant_tbl };
-
-
- typedef enum {false, true} boolean;
-
- /* switch table */
- static struct opt {
- char *string;
- enum { helpO, quietO, verboseO, offsetO, continueO, noContinueO,
- recurseO, noRecurseO, hexcharsO, nohexcharsO } id;
- } options[] = {
- {"?", helpO},
- {"help", helpO},
- {"quiet", quietO},
- {"verbose", verboseO},
- {"offset", offsetO},
- {"continueaftereoi", continueO},
- {"nocontinueaftereoi", noContinueO},
- {"recurseintojpegthumbnails", recurseO},
- {"norecurseintojpegthumbnails", noRecurseO},
- {"hex", hexcharsO},
- {"nohex", nohexcharsO}
- };
-
- static boolean hexchars; /* state of hex-chars switch */
-
-
- static long dumpMarkers(FILE *, char *, int, boolean, boolean, long);
- static unsigned int getWordMoto(FILE *);
-
-
- int
- main (int argc, char **argv)
- {
- FILE *inFile;
- int numFileNames;
- int i;
- int verbosity;
- boolean skipeoi, recurse;
- long offset, j;
-
- /* default switch settings */
- offset=0L;
- skipeoi=true;
- recurse=false;
- verbosity=0;
- hexchars=false;
-
- /* skip invocation name */
- argc--;
- argv++;
-
- /* scan arguments */
- numFileNames=0;
-
- while (argc) {
- if (**argv=='-'
- #ifdef MSDOS
- || **argv=='/'
- #endif
- ) {
- /* Process a switch */
- size_t length;
- int selectedOption;
- boolean multipleMatches;
-
- length=strlen((*argv)+1);
- selectedOption=-1;
- multipleMatches=false;
- for (i=0; i<sizeof(options)/sizeof(struct opt); i++) {
- if (strnicmp((*argv)+1, options[i].string, length)==0) {
- if (selectedOption>=0)
- if (options[i].id!=options[selectedOption].id)
- multipleMatches=true;
- selectedOption=i;
- if (length==strlen(options[i].string)) {
- multipleMatches=false;
- break;
- }
- }
- }
- if (selectedOption>=0 && !multipleMatches) {
- switch(options[selectedOption].id) {
- case helpO:
- fprintf(stderr,
- "usage: jpegdump [-help] [-q] [-v] [-o n] [-c] [-noc] [-r] [-nor] [-hex] [-nohex] [file1 [file2...]]\n");
- exit(0);
- break;
- case quietO:
- verbosity--;
- break;
- case verboseO:
- verbosity++;
- break;
- case offsetO:
- if (argc>1) {
- argc--;
- argv++;
- offset=atol(*argv);
- }
- break;
- case continueO:
- skipeoi=true;
- break;
- case noContinueO:
- skipeoi=false;
- break;
- case recurseO:
- recurse=true;
- break;
- case noRecurseO:
- recurse=false;
- break;
- case hexcharsO:
- hexchars=true;
- break;
- case nohexcharsO:
- hexchars=false;
- break;
- }
- } else if (multipleMatches) {
- fprintf(stderr, "ambiguous option %s\n", *argv);
- exit(-1);
- } else {
- fprintf(stderr, "unrecognized option %s\n", *argv);
- exit(-1);
- }
- } else {
- /* not a switch, process input file with current switch settings */
- numFileNames++;
- inFile=fopen(*argv, "rb");
- if (inFile==NULL) {
- fprintf(stderr, "can't open file %s\n", *argv);
- } else {
- printf("\n%s:\n", *argv);
- for (j=0L; j<offset; j++) /* skip specified offset */
- getc(inFile);
- dumpMarkers(inFile, "", verbosity, skipeoi, recurse, offset);
- fclose(inFile);
- }
- }
- argv++;
- argc--;
- }
-
- /* Process standard input if no file names were found */
- if (numFileNames==0) {
- inFile=stdin;
- #ifdef MSDOS
- /* turn off newline translation */
- setmode(fileno(inFile), O_BINARY);
- #endif
- for (j=0L; j<offset; j++) /* skip specified offset */
- getc(inFile);
- dumpMarkers(inFile, "", verbosity, skipeoi, recurse, offset);
- }
-
- return 0;
- }
-
-
- static void
- printChar (int c)
- {
- if (hexchars) {
- printf("$%02x ", c);
- } else {
- if (c == '\\')
- printf("\\\\");
- else if (isprint(c) || c == '\n')
- putchar(c);
- else
- printf("\\%03o", c);
- }
- }
-
-
- static long
- dumpMarkers (FILE *stream, char *prefix, int verbosity,
- boolean continueAfterEOI, boolean recurseIntoThumbnails,
- long startingOffset)
- {
- int marker;
- int c, c2, c3, c4, c5, row, col, i;
- unsigned int height, aword;
- long length;
- unsigned char huff[16];
- long totalBytesRead;
- char *str;
- char *newPrefix;
-
- totalBytesRead=0L;
-
- while (1) {
- c=getc(stream);
- if (c==EOF)
- break;
- totalBytesRead++;
- /* marker prefix? */
- if (c!=0xff)
- continue;
- /* get marker code, skipping fill bytes */
- do {
- c=getc(stream);
- totalBytesRead++;
- } while (c==0xff);
- if (c==EOF)
- break;
- /* ignore stuffed FF/00 sequences */
- if (c==0)
- continue;
- /* OK, we've apparently found a marker */
- marker=c;
- /* Minimum verbosity to print marker is 2 for RSTs, 0 for rest */
- if (verbosity>0 && (marker<RST+0 || marker>RST+7 || verbosity>2))
- printf("%soffset $%lx ", prefix, totalBytesRead+startingOffset-2L);
- length=0L;
- switch (marker) {
- case SOI:
- if (verbosity>0)
- printf("SOI\n");
- break;
- case DRI:
- length=(long) getWordMoto(stream);
- aword = getWordMoto(stream);
- if (verbosity>0) {
- printf("DRI (length %ld)\n", length);
- printf("%s restart interval %u MCUs\n", prefix, aword);
- }
- totalBytesRead+=4L;
- length-=4L;
- break;
- case APP+0:
- case APP+1:
- case APP+2:
- case APP+3:
- case APP+4:
- case APP+5:
- case APP+6:
- case APP+7:
- case APP+8:
- case APP+9:
- case APP+10:
- case APP+11:
- case APP+12:
- case APP+13:
- case APP+14:
- case APP+15:
- length=(long) getWordMoto(stream);
- if (verbosity>0)
- printf("APP%d (length %ld)\n", marker-APP, length);
- totalBytesRead+=2L;
- length-=2L;
-
- if (marker==APP+0 && length>=14L) {
- char signature[5];
-
- fread(signature, 1, 5, stream);
- totalBytesRead+=5L;
- length-=5L;
- if (memcmp(signature, "JFIF", 5)==0) {
- unsigned int dpiX, dpiY, thumbX, thumbY;
- long thumbBytes;
-
- aword = getWordMoto(stream);
- c=getc(stream);
- dpiX=getWordMoto(stream);
- dpiY=getWordMoto(stream);
- thumbX=(unsigned int) getc(stream);
- thumbY=(unsigned int) getc(stream);
- totalBytesRead+=9L;
- length-=9L;
- if (verbosity>0) {
- printf("%s JFIF version %04x, ", prefix, aword);
- switch (c) {
- case 0:
- printf("aspect ratio %u:%u\n", dpiX, dpiY);
- break;
- case 1:
- printf("%u x %u dpi\n", dpiX, dpiY);
- break;
- case 2:
- printf("%u x %u dpcm\n", dpiX, dpiY);
- break;
- default:
- printf("bogus aspect ratio code %d %u %u\n", c, dpiX, dpiY);
- break;
- }
- printf("%s thumbnail size %u x %u\n", prefix, thumbX, thumbY);
- }
- thumbBytes = (long)thumbX*(long)thumbY*3L;
- length-=thumbBytes;
- totalBytesRead+=thumbBytes;
- while (thumbBytes--)
- getc(stream);
- } else if (memcmp(signature, "JFXX", 5)==0) {
- int extension;
- unsigned int thumbX, thumbY;
- long thumbBytes;
-
- extension=getc(stream);
- totalBytesRead++;
- length--;
- switch (extension) {
- case 0x10:
- if (verbosity>0)
- printf("%s JFIF extension JPEG thumbnail\n", prefix);
- if (recurseIntoThumbnails) {
- long bytes;
-
- newPrefix=(char *) malloc(strlen(prefix)+5);
- if (newPrefix==NULL) {
- fprintf(stderr, "out of memory\n");
- exit(-1);
- }
- strcpy(newPrefix, prefix);
- strcat(newPrefix, " ");
- bytes=dumpMarkers(stream, newPrefix, verbosity-1,
- false, true, startingOffset+totalBytesRead);
- totalBytesRead+=bytes;
- length-=bytes;
- free(newPrefix);
- } else {
- while (length>0L) {
- getc(stream);
- totalBytesRead++;
- length--;
- }
- }
- break;
- case 0x11:
- if (verbosity>0)
- printf("%s JFIF extension 1 byte/pixel thumbnail\n", prefix);
- thumbX=(unsigned int) getc(stream);
- thumbY=(unsigned int) getc(stream);
- totalBytesRead+=2L;
- length-=2L;
- if (verbosity>0)
- printf("%s thumbnail size %u x %u\n", prefix, thumbX, thumbY);
- if (verbosity>2)
- printf("%s palette:\n", prefix);
- for (i=0; i<256; i++) {
- int red, green, blue;
- red=getc(stream);
- green=getc(stream);
- blue=getc(stream);
- totalBytesRead+=3L;
- length-=3L;
- if (verbosity>2)
- printf("%s %3d %3d %3d\n", prefix, red, green, blue);
- }
- thumbBytes = (long)thumbX*(long)thumbY;
- length-=thumbBytes;
- totalBytesRead+=thumbBytes;
- while (thumbBytes--)
- getc(stream);
- break;
- case 0x13:
- if (verbosity>0)
- printf("%s JFIF extension 3 byte/pixel thumbnail\n", prefix);
- thumbX=(unsigned int) getc(stream);
- thumbY=(unsigned int) getc(stream);
- totalBytesRead+=2L;
- length-=2L;
- if (verbosity>0)
- printf("%s thumbnail size %u x %u\n", prefix, thumbX, thumbY);
- thumbBytes = (long)thumbX*(long)thumbY*3L;
- length-=thumbBytes;
- totalBytesRead+=thumbBytes;
- while (thumbBytes--)
- getc(stream);
- break;
- default:
- if (verbosity>0)
- printf("%s JFIF extension $%02x\n", prefix, extension);
- break;
- }
- } else {
- /* Unrecognized APP0 marker */
- if (verbosity>0) {
- printf("%s ", prefix);
- for (i=0; i<5; i++)
- printChar((int) signature[i]);
- }
- while (length>0L) {
- c = getc(stream);
- if (verbosity>0)
- printChar(c);
- totalBytesRead++;
- length--;
- }
- if (verbosity>0)
- printf("\n");
- }
- }
- /* Print any remaining data in the APP marker */
- if (length) {
- if (verbosity>0)
- printf("%s ", prefix);
- while (length>0L) {
- c = getc(stream);
- if (verbosity>0)
- printChar(c);
- totalBytesRead++;
- length--;
- }
- if (verbosity>0)
- printf("\n");
- }
- break;
- case COM:
- length=(long) getWordMoto(stream);
- if (verbosity>0)
- printf("COM (length %ld)\n ", length);
- totalBytesRead+=2L;
- length-=2L;
- while (length>0L) {
- c = getc(stream);
- if (verbosity>0)
- printChar(c);
- totalBytesRead++;
- length--;
- }
- if (verbosity>0)
- printf("\n");
- break;
- /* the following all have the same syntax and fall through to one parser */
- case SOF+0:
- str="SOF0 (baseline DCT Huffman)";
- goto frame;
- case SOF+1:
- str="SOF1 (extended sequential DCT Huffman)";
- goto frame;
- case SOF+2:
- str="SOF2 (progressive DCT Huffman)";
- goto frame;
- case SOF+3:
- str="SOF3 (spatial lossless Huffman)";
- goto frame;
- case SOF+9:
- str="SOF9 (extended sequential DCT arithmetic)";
- goto frame;
- case SOF+10:
- str="SOF10 (progressive DCT arithmetic)";
- goto frame;
- case SOF+11:
- str="SOF11 (spatial lossless arithmetic)";
- goto frame;
- /* the following SOF markers are for differential coding;
- they are listed on page B-2 of CD 10918-1, but for some
- reason are not listed on B-6 and B-7, where the SOF syntax
- is given. This suggests that the syntax may be different
- for these markers, but it doesn't seem to be defined
- anywhere else in the document. */
- case SOF+5:
- str="SOF5 (differential sequential DCT Huffman)";
- goto frame;
- case SOF+6:
- str="SOF6 (differential progressive DCT Huffman)";
- goto frame;
- case SOF+7:
- str="SOF7 (differential spatial Huffman)";
- goto frame;
- case SOF+13:
- str="SOF13 (differential sequential DCT arithmetic)";
- goto frame;
- case SOF+14:
- str="SOF14 (differential progressive DCT arithmetic)";
- goto frame;
- case SOF+15:
- str="SOF15 (differential spatial arithmetic)";
- goto frame;
- case DHP:
- str="DHP";
-
- frame:
- length=(long) getWordMoto(stream);
- if (verbosity>0)
- printf("%s (length %ld)\n", str, length);
- totalBytesRead+=2L;
- length-=2L;
- c=getc(stream);
- height=getWordMoto(stream);
- aword=getWordMoto(stream);
- c2=getc(stream);
- totalBytesRead+=6L;
- length-=6L;
- if (verbosity>0)
- printf("%s sample precision %d\n", prefix, c);
- if (verbosity>= -1) /* even very terse output includes dimensions */
- printf("%s width %u, height %u components %d\n", prefix,
- aword, height, c2);
- while (c2--) {
- c3=getc(stream);
- c4=getc(stream);
- c5=getc(stream);
- totalBytesRead+=3L;
- length-=3L;
- if (verbosity>=0) /* terse output includes sampling factors */
- printf("%s id %d horizontal sampling %d, vertical sampling %d, quantization table %d\n", prefix, c3, c4>>4, c4&0x0f, c5);
- }
- break;
- case SOS:
- length=(long) getWordMoto(stream);
- if (verbosity>0)
- printf("SOS (length %ld)\n", length);
- totalBytesRead+=2L;
- length-=2L;
- c2=getc(stream);
- totalBytesRead++;
- length--;
- if (verbosity>0)
- printf("%s components %d\n", prefix, c2);
- while (c2--) {
- c3=getc(stream);
- c4=getc(stream);
- totalBytesRead+=2L;
- length-=2L;
- if (verbosity>0)
- printf("%s id %d dc table %d, ac table %d\n", prefix,
- c3, c4>>4, c4&0x0f);
- }
- c=getc(stream);
- c2=getc(stream);
- c3=getc(stream);
- totalBytesRead+=3L;
- length-=3L;
- if (verbosity>0)
- printf("%s spectral selection %d to %d, bit position high %d, low %d\n",
- prefix, c, c2, c3>>4, c3&0x0f);
- break;
- case DQT:
- length=(long) getWordMoto(stream);
- if (verbosity>0)
- printf("DQT (length %ld)\n", length);
- totalBytesRead+=2L;
- length-=2L;
-
- while (length>0L) {
- int tableindex;
- int *table = NULL;
- double cumsf = 0.0, cumsf2 = 0.0;
- int allones = 1;
-
- c=getc(stream);
- totalBytesRead++;
- length--;
- tableindex = c & 0x0f;
- if (verbosity>0)
- printf("%s table %d precision %d\n", prefix, tableindex,
- (c>>4) ? 16 : 8);
- if (tableindex < 2)
- table = deftabs[tableindex];
-
- for (row=0; row<8; row++) {
- if (verbosity>1)
- printf("%s ", prefix);
- for (col=0; col<8; col++) {
- unsigned int val;
-
- if (c>>4) {
- val=getWordMoto(stream);
- totalBytesRead+=2L;
- length-=2L;
- } else {
- val=(unsigned int) getc(stream);
- totalBytesRead++;
- length--;
- }
- if (verbosity>1)
- printf("%5u ", val);
- if (table) {
- double x;
- /* scaling factor in percent */
- x = 100.0 * (double)val / (double)table[row*8+col];
- cumsf += x;
- cumsf2 += x * x;
- /* separate check for all-ones table (Q 100) */
- if (val != 1) allones = 0;
- }
- }
- if (verbosity>1)
- printf("\n");
- }
- if (table) {
- double qual, var;
-
- cumsf /= 64.0; /* mean scale factor */
- cumsf2 /= 64.0;
- var = cumsf2 - (cumsf * cumsf); /* variance */
- if (allones) /* special case for all-ones table */
- qual = 100.0;
- else if (cumsf <= 100.0)
- qual = (200.0 - cumsf) / 2.0;
- else
- qual = 5000.0 / cumsf;
- if (verbosity>=0) /* terse output includes quality */
- printf("%s Approximate quality factor for qtable %d: %.0f (scale %.2f, var %.2f)\n", prefix,
- tableindex, qual, cumsf, var);
- }
- }
- break;
- case DHT:
- length=(long) getWordMoto(stream);
- if (verbosity>0)
- printf("DHT (length %ld)\n", length);
- totalBytesRead+=2L;
- length-=2L;
- while (length>0L) {
- c=getc(stream);
- totalBytesRead++;
- length--;
- if (verbosity>0)
- printf("%s table %d\n", prefix, c);
- for (i=0; i<16; i++) {
- huff[i]=(unsigned char) getc(stream);
- }
- totalBytesRead+=16L;
- length-=16L;
- for (i=0; i<16; i++) {
- if (verbosity>1)
- printf("%s bits %2d (codes=%3u) ", prefix, i+1,
- (unsigned int) huff[i]);
- while (huff[i]--) {
- c2 = getc(stream);
- totalBytesRead++;
- length--;
- if (verbosity>1)
- printf("$%02x ", c2);
- }
- if (verbosity>1)
- printf("\n");
- }
- }
- break;
- case DAC:
- length=(long) getWordMoto(stream);
- if (verbosity>0)
- printf("DAT (length %ld)\n", length);
- totalBytesRead+=2L;
- length-=2L;
- while (length>0L) {
- c=getc(stream);
- c2=getc(stream);
- totalBytesRead+=2L;
- length-=2L;
- if (verbosity>0)
- printf("%s id %d conditioning %d\n", prefix, c, c2);
- }
- break;
- case RST+0:
- case RST+1:
- case RST+2:
- case RST+3:
- case RST+4:
- case RST+5:
- case RST+6:
- case RST+7:
- if (verbosity>2)
- printf("RST%d\n", marker-RST);
- break;
- case DNL:
- length=(long) getWordMoto(stream);
- aword = getWordMoto(stream);
- totalBytesRead+=4L;
- length-=4L;
- if (verbosity>0) {
- printf("DNL (length %ld)\n", length);
- printf("%s lines %u\n", prefix, aword);
- }
- break;
- case EOI:
- if (verbosity>0)
- printf("EOI\n");
- break;
- case EXP:
- length=(long) getWordMoto(stream);
- if (verbosity>0)
- printf("DHP (length %ld)\n", length);
- c=getc(stream);
- if (verbosity>0)
- printf("%s horizontal expansion %d, vertical expansion %d\n", prefix,
- c>>4, c&0x0f);
- totalBytesRead+=3L;
- length-=3L;
- break;
- case TEM:
- if (verbosity>0)
- printf("TEM\n");
- break;
- default:
- length=(long) getWordMoto(stream);
- if (verbosity>0)
- printf("marker $%02x (length %ld)\n", c, length);
- totalBytesRead+=2L;
- length-=2L;
- if (verbosity>0)
- printf("%s ", prefix);
- while (length>0L) {
- c=getc(stream);
- totalBytesRead++;
- length--;
- if (verbosity>0)
- printChar(c);
- }
- if (verbosity>0)
- printf("\n");
- break;
- } /* end switch (marker) */
- if (length && verbosity>0)
- printf("%s bad length (residual=%ld)\n", prefix, length);
- if (marker==EOI && !continueAfterEOI)
- break;
- } /* end while */
-
- return totalBytesRead;
- }
-
-
- static unsigned int
- getWordMoto (FILE *stream)
- {
- register unsigned int temp;
-
- temp=(unsigned int) (getc(stream)<<8);
- return (unsigned int) getc(stream) | temp;
- }
-